package dasregistry.validation;

import java.util.List;
import java.util.Map;

import org.biojava.dasobert.das.Capabilities;
import org.biojava.dasobert.das.DasSpec;
import org.biojava.dasobert.dasregistry.Das1Validator;
import org.biojava.dasobert.dasregistry.Das1_6Validator;
import org.biojava.dasobert.dasregistry.DasCoordinateSystem;
import org.biojava.dasobert.dasregistry.DasSource;
import org.biojava.dasobert.dasregistry.DasValidationResult;
import org.biojava.dasobert.dasregistry.ValidationResultLights;

import org.biojava.services.das.registry.CapabilityLinkBean;
import org.biojava.services.das.registry.DasRegistry;
import org.biojava.services.das.registry.DasRegistrySql;
import org.biojava.services.das.registry.RegistryConfiguration;
import org.biojava.services.das.registry.ShowLinkCapability;



/**
 * one class as a wrapper for the DASValidation classes so that we can use one
 * method for validation throughout the code
 * 
 * @author jw12
 * 
 */
public class Validator {
	

	public ValidationResultLights getLights(DasSpec spec, String url,
			List<String> capabilities, DasCoordinateSystem[] dcsses,
			boolean validateOntology, boolean updateDatabase,
			DasRegistry registry, String auto_id, String queryUri) {

		DasValidationResult result = validate(spec, url, capabilities, dcsses,
				validateOntology, updateDatabase, registry, auto_id);
	
		
		Capabilities[] caps=Capabilities.capabilitiesFromStrings(capabilities);
		ValidationResultLights lights=new ValidationResultLights(result, caps);
		return lights;
	}

	/*
	 * we need a method that takes a source and validates it with all coordinate
	 * systems and all the possible capabilities then produces a result that is
	 * the same as the colors in the list of validated servers for both the
	 * autovalidation and the web page validation and registering a new source. Would be good to have a error
	 * message String associated with each capability as a map we want a
	 * registry reference as we don't want to be creating a new one everytime we
	 * want to write to a database - if new registry don't update databaseauto
	 * id is needed for validating on web pages as we then know there should be
	 * an entry
	 */

	public DasValidationResult validate(DasSpec spec, String url,
			List<String> statedCaps, DasCoordinateSystem[] dcsses,
			boolean validateOntology, boolean updateDatabase,
			DasRegistry registry, String auto_id) {

		boolean allValid = false;
		DasValidationResult result=null;
		
		RegistryConfiguration rconfig = new RegistryConfiguration();
		// rconfig is set by the outside via Spring
		Map configuration = rconfig.getConfiguration();

		String relaxNgPath1_5 = (String) configuration.get("relaxNgPath1_5");
		String relaxNgPath1_6 = (String) configuration.get("relaxNgPath1_6");
		// dont need to validate all capabilities for each
		// coordinate system but this is actually handled in the DAS1/1.6
		// validators - however we don't store the info!!
		Das1Validator dvl = null;
		if (spec.equals(DasSpec.SPEC1_53E)) {

			dvl = new Das1Validator();
			if (relaxNgPath1_5 != null) {
				dvl.setRelaxNgPath(relaxNgPath1_5);
			}
		} else {
			dvl = new Das1_6Validator();// extends das1validator

			if (relaxNgPath1_6 != null) {
				dvl.setRelaxNgPath(relaxNgPath1_6);
			}
		}

		if (validateOntology) {
			result = dvl.validate(url, dcsses, statedCaps,
					dvl.VERBOSE, Das1Validator.ONTOLOGY_VALIDATION);
		} else {
			result = dvl.validate(url, dcsses, statedCaps,false, false);
		}
		List<String> caps = result.getValidCaps();

		if (result != null && statedCaps != null) {
			List<String> notValidButStated = Capabilities.containsSubSet(
					statedCaps, caps);
			if (notValidButStated.size() == 0) {
				allValid = true;
				result.setOverallValid(true);
			}
			
			if ((auto_id != "") && (auto_id != null)) {

				DasSource ds = ((DasRegistrySql) registry)
						.getDasSourceByURL(url);
				// if datasource is found in database set the new
				// validation capabilities we have just found for this
				// datasource
				if (ds != null) {
					System.out.println("ds!=null so updating source in registry"+ds.getUrl());
					ds.setValidCapabilities(caps);
					// update the database so lights will be correct
					//System.out.println("running  update validation");
					registry.updateValidCapabilities(ds);
					registry.updateTimes(result.getTimes(), ds);
					registry.updateTypes(result.getTypes(), ds);
							
					if(caps.size()==0){
					//if no valid caps for the url assume is down and don't renew lease so emails will be sent and after say 2months we can archive the source	
					//System.out.println("no valid capabilities so not renewing lease for url="+url);
					}else{
					//if a valid response for anything then renew lease
					//if all valid that were stated then put a 1 in the database to say so
					registry.renewLease(url, allValid);
					}

				}

			}

		}

		return result;
	}
	
	

}
